Skip to content

refactor(sdk): remove deprecated v1 split build/sign transaction surface - #4323

Merged
QuantumExplorer merged 2 commits into
v4.2-devfrom
claude/focused-liskov-bd0975
Aug 6, 2026
Merged

refactor(sdk): remove deprecated v1 split build/sign transaction surface#4323
QuantumExplorer merged 2 commits into
v4.2-devfrom
claude/focused-liskov-bd0975

Conversation

@QuantumExplorer

@QuantumExplorer QuantumExplorer commented Aug 6, 2026

Copy link
Copy Markdown
Member

Issue being fixed or feature implemented

The v1 split Core-send path (set_fundingbuild_signed → broadcast) is concurrency-unsafe by construction: funding selection and signing are split across the C ABI, so the wallet-manager lock cannot be held across the boundary and two concurrent same-account builds can select the same UTXO (a double-spend at broadcast). The atomic finalizers (#4185 and the deferred flow in #4308/#4322) were built to close this, every SDK convenience path already routes through them, and an audit found zero remaining in-repo call sites — the split path survived only as exported API/ABI, where keeping it publicly reachable (especially in Swift) invites misuse.

What was done?

Removed the v1 surface across the stack:

  • rs-platform-wallet-ffi: core_wallet_tx_builder_set_funding, core_wallet_tx_builder_build_signed, core_wallet_broadcast_transaction, plus the now-dead CoreAccountTypeFFI::as_standard_account_type / managed_account_mut helpers. FFICoreTransaction and core_wallet_transaction_free are kept: they are the ownership-transfer mechanism of the v2 core_wallet_signed_payment_finalize out-params (feat(swift-sdk): split build/broadcast with reservation release for BIP70-style deferred submission #4322), so they are no longer v1-only.
  • rs-unified-sdk-jni: the coreTxBuilderSetFunding, coreTxBuilderBuildSigned, coreWalletBroadcastTransaction, coreTransactionFree trampolines.
  • kotlin-sdk: the deprecated internal setFunding/buildSigned, the CoreTransaction class, the v1 broadcastTransaction(CoreTransaction) overload, and the matching external funs.
  • swift-sdk: the deprecated public setFunding/buildSigned, the CoreTransaction type, and both v1 broadcast entry points (broadcastTransactionWithOutcome(_: CoreTransaction) and the deprecated throwing wrapper).
  • Every stale doc/comment reference to the removed names (including the example-app TEST_PLAN flow notes).

The parity manifest has no shared_symbols entries for the removed functions (verified).

dashwallet-ios was the one out-of-repo consumer; it is migrated to finalizeAtomic on dashwallet-ios branch feat/migrate-v2-atomic-send, which should land before the platform pin there advances past this PR.

How Has This Been Tested?

  • cargo check / cargo clippy --all-targets / cargo fmt on platform-wallet-ffi, rs-unified-sdk-jni, rs-sdk-ffi (clippy: only pre-existing warnings in untouched persistence.rs)
  • cargo test -p platform-wallet-ffi: 235 + 26 + 6 pass
  • Kotlin: :sdk:compileDebugKotlin, :sdk:compileDebugAndroidTestKotlin, :sdk:testDebugUnitTest all green
  • Swift: swift build + SignedCoreTransactionTests (5 tests) green against a freshly built xcframework at this commit

Breaking Changes

None consensus-level. Pre-release SDK API removal; the replacement atomic surface has been in place since #4185/#4322.

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

🤖 Generated with Claude Code

Summary by CodeRabbit

  • API Updates
    • Updated Kotlin and Swift wallet transaction flows to use atomic finalization and signed-payment broadcasting.
    • Removed deprecated split funding, signing, legacy broadcasting, and transaction ownership APIs.
    • Swift wallets can now abandon finalized transactions to release reservations.
    • Deferred payments continue to support signed-payment finalization and broadcasting workflows.
  • Documentation
    • Updated SDK documentation and test plans to reflect the current finalization and broadcasting workflows.

Remove the concurrency-unsafe split fund-then-sign Core send path across
the SDK stack, superseded by the atomic finalizers (finalize/v2 broadcast
and the deferred signed-payment flow):

- rs-platform-wallet-ffi: drop core_wallet_tx_builder_set_funding,
  core_wallet_tx_builder_build_signed and core_wallet_broadcast_transaction
  (with the now-dead as_standard_account_type / managed_account_mut
  helpers). FFICoreTransaction and core_wallet_transaction_free stay: they
  are the ownership-transfer mechanism of the v2
  core_wallet_signed_payment_finalize out-params.
- rs-unified-sdk-jni: drop the coreTxBuilderSetFunding,
  coreTxBuilderBuildSigned, coreWalletBroadcastTransaction and
  coreTransactionFree trampolines.
- kotlin-sdk: drop the deprecated internal setFunding/buildSigned, the
  CoreTransaction class, the v1 broadcastTransaction(CoreTransaction)
  overload and the matching external funs.
- swift-sdk: drop the deprecated public setFunding/buildSigned, the
  CoreTransaction type and both v1 broadcast entry points
  (broadcastTransactionWithOutcome/broadcastTransaction over
  CoreTransaction).

The split path raced funding selection against signing across the C ABI
(two concurrent same-account builds could select the same UTXO); the
atomic finalizers commit selection + reservation under one wallet-manager
lock. An audit found no remaining in-repo call sites; dashwallet-ios is
migrated to finalizeAtomic separately before this lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2daf69a4-f5b2-459d-a4a6-5f82e1b69ae1

📥 Commits

Reviewing files that changed from the base of the PR and between f9639aa and 2f2cd07.

📒 Files selected for processing (2)
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt
  • packages/rs-platform-wallet-ffi/src/core_wallet/transaction_builder.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt

📝 Walkthrough

Walkthrough

The change removes legacy split transaction-building, transaction ownership, and broadcast APIs. Rust FFI, JNI, Kotlin, and Swift now use atomic finalizers, V2 signed-transaction broadcasting, deferred payment handling, and finalized-transaction abandonment.

Changes

Atomic finalization and broadcast migration

Layer / File(s) Summary
Rust FFI finalization surface
packages/rs-platform-wallet-ffi/src/core_wallet/transaction_builder.rs, packages/rs-platform-wallet-ffi/src/core_wallet/signed_payment.rs
Removes split funding/build APIs and updates transaction ownership, reservation, height, and finalizer documentation.
JNI and Kotlin API removal
packages/rs-unified-sdk-jni/src/wallet_manager.rs, packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/*, packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/wallet/*
Removes legacy JNI and Kotlin declarations for builder funding, signed builds, transaction broadcast, transaction cleanup, and CoreTransaction.
Swift finalized transaction handling
packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/CoreWallet/*
Broadcasts FinalizedCoreTransaction values, maps outcomes, supports deferred signed-payment tokens, and adds transaction abandonment.
SDK lifecycle documentation and test plans
packages/kotlin-sdk/KotlinExampleApp/TEST_PLAN.md, packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/NativePersistenceBridge.kt, packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/wallet/ManagedPlatformWallet.kt, packages/swift-sdk/SwiftExampleApp/TEST_PLAN.md
Updates lifecycle documentation and CORE-10 test plans for atomic finalization and V2 broadcasting.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ManagedCoreWallet
  participant FinalizedCoreTransaction
  participant core_wallet_broadcast_signed_transaction_v2
  ManagedCoreWallet->>FinalizedCoreTransaction: consume finalized transaction
  ManagedCoreWallet->>core_wallet_broadcast_signed_transaction_v2: broadcast signed transaction
  core_wallet_broadcast_signed_transaction_v2-->>ManagedCoreWallet: return broadcast outcome
Loading

Possibly related issues

Possibly related PRs

Suggested reviewers: lklimek, llbartekll, shumkov

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: removing the deprecated v1 split build/sign transaction API surface across the SDK layers.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/focused-liskov-bd0975

Comment @coderabbitai help to get the list of available commands.

@thepastaclaw

thepastaclaw commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

🔍 Review in progress — actively reviewing now (commit 2f2cd07)
Stage: Codex precheck starting
ETA: complete ~20:00 UTC (median 20m across 30 recent reviews)
Running 9m · Last checked: 2026-08-06 19:50 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt (1)

202-202: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the V2 transaction-handle term.

coreTxBuilderFinalize returns an opaque signed-transaction V2 handle. It does not return the deferred-payment registry token. The current text can cause callers to apply the wrong ownership model.

Proposed fix
-    /** Atomic V2 finalizer; consumes [builder] and returns an opaque registry handle. */
+    /** Atomic V2 finalizer; consumes [builder] and returns an opaque signed-transaction V2 handle. */
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt`
at line 202, Update the documentation comment for coreTxBuilderFinalize to
describe its result as an opaque signed-transaction V2 handle, not a registry
handle or deferred-payment token. Keep the note that the operation is an atomic
V2 finalizer consuming builder.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt`:
- Line 202: Update the documentation comment for coreTxBuilderFinalize to
describe its result as an opaque signed-transaction V2 handle, not a registry
handle or deferred-payment token. Keep the note that the operation is an atomic
V2 finalizer consuming builder.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7441ccc8-c5b5-4702-a2df-2aebbd023cc6

📥 Commits

Reviewing files that changed from the base of the PR and between 316ee7a and f9639aa.

📒 Files selected for processing (13)
  • packages/kotlin-sdk/KotlinExampleApp/TEST_PLAN.md
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/NativePersistenceBridge.kt
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/ffi/WalletManagerNative.kt
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/wallet/CoreTransactionBuilder.kt
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/wallet/ManagedCoreWallet.kt
  • packages/kotlin-sdk/sdk/src/main/kotlin/org/dashfoundation/dashsdk/wallet/ManagedPlatformWallet.kt
  • packages/rs-platform-wallet-ffi/src/core_wallet/broadcast.rs
  • packages/rs-platform-wallet-ffi/src/core_wallet/signed_payment.rs
  • packages/rs-platform-wallet-ffi/src/core_wallet/transaction_builder.rs
  • packages/rs-unified-sdk-jni/src/wallet_manager.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/CoreWallet/CoreTransactionBuilder.swift
  • packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/CoreWallet/ManagedCoreWallet.swift
  • packages/swift-sdk/SwiftExampleApp/TEST_PLAN.md
💤 Files with no reviewable changes (2)
  • packages/rs-platform-wallet-ffi/src/core_wallet/broadcast.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/CoreWallet/ManagedCoreWallet.swift

@thepastaclaw thepastaclaw left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final validation — Codex + Opus

The deprecated split transaction surface is removed consistently across Rust FFI, JNI, Kotlin, and Swift, with the retained V2 and deferred-finalization ownership paths remaining intact. No correctness, security, ABI, dependency-direction, or consensus issues were verified; two in-scope documentation nitpicks remain: stale JNI references to the deleted API and an introduced source-formatting regression in a Rust doc comment.
Source: reviewer backend models gpt-5.6-sol and claude-sonnet-5; final verifier backend model gpt-5.6-sol, used as the permitted fallback after both claude-sonnet-5 verifier attempts produced unparseable output. openclaw-agent/cliproxy/gpt-5.6-sol is orchestration-only and not reviewer evidence.

Review provenance

  • Codex reviewers: gpt-5.6-sol — general (completed), gpt-5.6-sol — security-auditor (completed), gpt-5.6-sol — ffi-engineer (completed)
  • Verifier: gpt-5.6-sol — final-verifier (Opus verifier fallback)
  • Opus reviewers: claude-sonnet-5 — general (completed), claude-sonnet-5 — security-auditor (failed), claude-sonnet-5 — ffi-engineer (completed), claude-sonnet-5 — security-auditor (completed)

💬 2 nitpick(s)

1 additional finding(s) omitted (not in diff).

Comment on lines 78 to 80
/// Selection and insertion into the account ReservationSet happen under one
/// wallet-manager lock, so they cannot interleave with a competing finalizer. The wallet-manager lock is dropped before the host
/// mnemonic resolver is invoked. This function consumes `builder` on every

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💬 Nitpick: Restore the source wrapping in the finalizer documentation

The updated comment joins the end of one sentence and the start of the next on a single unusually long source line. Rustdoc rendering is unaffected, but this PR introduced a source-formatting regression while removing the deprecated API reference, and the line no longer follows the wrapping style used by the surrounding documentation.

Suggested change
/// Selection and insertion into the account ReservationSet happen under one
/// wallet-manager lock, so they cannot interleave with a competing finalizer. The wallet-manager lock is dropped before the host
/// mnemonic resolver is invoked. This function consumes `builder` on every
/// Selection and insertion into the account ReservationSet happen under one
/// wallet-manager lock, so they cannot interleave with a competing finalizer.
/// The wallet-manager lock is dropped before the host mnemonic resolver is
/// invoked. This function consumes `builder` on every path after its pointer

source: ['claude']

Restore the wrapped line the removal edit joined in the
core_wallet_tx_builder_finalize doc, and describe coreTxBuilderFinalize's
result as a signed-transaction V2 handle rather than a registry handle
(the registry token belongs to the deferred signed-payment flow).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@QuantumExplorer QuantumExplorer left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed

@QuantumExplorer
QuantumExplorer merged commit 99a5ce2 into v4.2-dev Aug 6, 2026
1 check passed
@QuantumExplorer
QuantumExplorer deleted the claude/focused-liskov-bd0975 branch August 6, 2026 19:54
@github-actions github-actions Bot added this to the v4.2.0 milestone Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants